發燒第三天,現在只打得出流水帳,等完賽再修
每個物件都會有個[[prototype]]
屬性指向該物件的原型,
當存取物件不存在的屬性或方法時,會往原型去搜尋,還沒找到的話會再往原型的原型去找,
這種由原型將各個物件串起來就叫做原型鍊
每個原型鍊的最底部為Object.prototype
,
所以在這邊加入方法的話,所有值都能使用這個方法
Object.prototype是所有原型鍊的最底端,
如果在這新增方法,所有值都能使用這個方法
舉個例子
Object.prototype.print = function () {
console.log(this);
};
'a'.print();//印出值為a的string物件
[1, 2, 3].print();//[1,2,3]
每個函式的原型物件都會有的屬性,會指向建構器函式,
利用原型鍊跟constructor
可以知道物件是由哪個建構器函式建立的
function People(name, age) {
this.name = name;
this.age = age;
}
var person1 = new People('John', 20);
console.log(person1.constructor === People);//true
//person1自己沒有constructor屬性,會原型鍊往People.prototype去找
//會在People.prototype找到constructor屬性(指向People)
function People(name, age) {
this.name = name;
this.age = age;
}
People.prototype.say = function () {
console.log('你好我叫做' + this.name + ',我今年' + this.age);
};
function Student(name, age, school) {
People.call(this, name, age);
this.school = school;
}
Student.prototype = new People();
var student1 = new Student('小明', 22, '社區大學');
上面程式想讓Sudent
建立出來的物件也能使用People
的方法,
所以手動將Sudent.prototype
設為People
建立出來的物件,
從Sudent
建立的student1
物件想呼叫say()
方法時,會經由原型鍊
從student->Student.prototype
(新建立的People物件)->People.prototype
找到say()
方法
要注意的是這樣覆寫prototype
會使constructor
屬性指向錯誤的地方
console.log(student1.constructor);//People
//本來應該指向Student的
解決方式很簡單 覆寫prototype
後把constructor
屬性加回去就是了
Object.defineProperty(Student.prototype, 'constructor', {
enumerable: false, //讓constructor不會被for...in列舉
value: Student,
});